package gl.java.umsp;

import io.netty.channel.ChannelDuplexHandler;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelPipeline;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;
import io.netty.handler.timeout.IdleStateHandler;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.TimeUnit;


@Slf4j
@ChannelHandler.Sharable
public class UmspAutoHeartBeatHandler extends ChannelDuplexHandler {
    private UmspAutoHeartBeatHandler() {
    }

    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        if (IdleStateEvent.class.isAssignableFrom(evt.getClass())) {
            IdleStateEvent event = (IdleStateEvent) evt;
            if (event.state() == IdleState.READER_IDLE) {
                log.warn("READER_IDLE,close the channel " + ctx.channel());
                ctx.channel().close();
            } else if (event.state() == IdleState.WRITER_IDLE) {
                Umsp.returnHeart(ctx.channel());
//                log.info("WRITER_IDLE idle " + ctx.channel());
            } else if (event.state() == IdleState.ALL_IDLE) {
//                log.info("ALL_IDLE " + ctx.channel());
            }
            log.info("heart beat");
        }
    }

    public static UmspAutoHeartBeatHandler newHandler(ChannelPipeline cp) {
        cp.addLast(new IdleStateHandler(0, UmspConfig.IDLE, 0, TimeUnit.MILLISECONDS));
        log.info("Register auto sending a UmspHeartBeat to Server pre " + UmspConfig.IDLE + "ms");
        return new UmspAutoHeartBeatHandler();
    }

    public static UmspAutoHeartBeatHandler newTimeOutCloseHandler(ChannelPipeline cp) {
        cp.addLast(new IdleStateHandler(UmspConfig.IDLE, 0, 0, TimeUnit.MILLISECONDS){
            @Override
            public void read(ChannelHandlerContext ctx) throws Exception {
                super.read(ctx);
            }
            public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
                super.channelReadComplete(ctx);
                log.info("IdleStateHandler.channelReadComplete");
            }
        });
        log.info("Register auto close when read time out  ,check at " + UmspConfig.IDLE + "ms");
        return new UmspAutoHeartBeatHandler();
    }
}
